From 8c8634474168e95acb3d2226677a7a5f2fdd170c Mon Sep 17 00:00:00 2001 From: "kaf24@viper.(none)" Date: Mon, 31 Jan 2005 23:16:27 +0000 Subject: [PATCH] bitkeeper revision 1.1159.212.60 (41febc4bKKSkh9u-Zes9v2CmBuLZxA) More bootstrap fixes for x86/64. Next thing to do is sort out the IDT and get traps.c working; then we can get rid of a bunch of dummy labels from end of boot/x86_64.S. We're also going to need some kind of entry.S before we can safely enable interrupts. Also bear in mind that not all of physical RAM may be mapped (only first 1GB) and no m2p table is yet allocated or mapped. Plenty to be done! --- .rootkeys | 4 +- xen/arch/x86/boot/x86_64.S | 10 +- xen/arch/x86/memory.c | 13 +-- xen/arch/x86/setup.c | 4 + xen/arch/x86/x86_32/mm.c | 68 +++++++++---- xen/arch/x86/x86_64/mm.c | 121 ++++++++++++++++++----- xen/include/asm-x86/config.h | 43 +++++--- xen/include/asm-x86/domain_page.h | 34 +------ xen/include/asm-x86/fixmap.h | 10 +- xen/include/asm-x86/mm.h | 6 -- xen/include/asm-x86/page.h | 40 +++++--- xen/include/asm-x86/x86_32/domain_page.h | 29 ++++++ xen/include/asm-x86/x86_64/domain_page.h | 13 +++ 13 files changed, 269 insertions(+), 126 deletions(-) create mode 100644 xen/include/asm-x86/x86_32/domain_page.h create mode 100644 xen/include/asm-x86/x86_64/domain_page.h diff --git a/.rootkeys b/.rootkeys index 4db5eae27f..c4161fdbf4 100644 --- a/.rootkeys +++ b/.rootkeys @@ -999,7 +999,7 @@ 3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h 3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h 40715b2dTokMLYGSuD58BnxOqyWVew xen/include/asm-x86/div64.h -3e20b82fl1jmQiKdLy7fxMcutfpjWA xen/include/asm-x86/domain_page.h +41febc4bBKTKHhnAu_KPYwgNkHjFlg xen/include/asm-x86/domain_page.h 41d3eaaeIBzW621S1oa0c2yk7X43qQ xen/include/asm-x86/e820.h 3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen/include/asm-x86/fixmap.h 3e2d29944GI24gf7vOP_7x8EyuqxeA xen/include/asm-x86/flushtlb.h @@ -1036,12 +1036,14 @@ 41c0c412lQ0NVVN9PsOSznQ-qhOiPA xen/include/asm-x86/vmx_vmcs.h 418fbcfe_WliJPToeVM-9VStvym-hw xen/include/asm-x86/x86_32/asm_defns.h 3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/include/asm-x86/x86_32/current.h +3e20b82fl1jmQiKdLy7fxMcutfpjWA xen/include/asm-x86/x86_32/domain_page.h 3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/regs.h 3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h 3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h 41bf1717bML6GxpclTWJabiaO5W5vg xen/include/asm-x86/x86_64/asm_defns.h 404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h 404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h +41febc4b1aCGLsm0Y0b_82h7lFtrEA xen/include/asm-x86/x86_64/domain_page.h 404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h 404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86/x86_64/regs.h 40e1966azOJZfNI6Ilthe6Q-T3Hewg xen/include/asm-x86/x86_64/string.h diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 73a513f9b6..a35b192917 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -248,19 +248,11 @@ ENTRY(cpu0_stack) # Initial stack is 8kB ENTRY(stext) ENTRY(_stext) -.globl map_domain_mem, unmap_domain_mem, ret_from_intr -map_domain_mem: -unmap_domain_mem: +.globl ret_from_intr, copy_to_user, set_intr_gate, die ret_from_intr: -#undef machine_to_phys_mapping -#undef phys_to_machine_mapping -.globl copy_to_user, set_intr_gate, die, machine_to_phys_mapping -.globl phys_to_machine_mapping copy_to_user: set_intr_gate: die: -machine_to_phys_mapping: -phys_to_machine_mapping: .globl copy_from_user, show_registers, do_iopl copy_from_user: show_registers: diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index cfc37e84aa..668a8c4af4 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -148,27 +148,20 @@ unsigned long max_page; void __init init_frametable(void) { -#if defined(__i386__) unsigned long i, p; -#endif + frame_table = (struct pfn_info *)FRAMETABLE_VIRT_START; frame_table_size = max_page * sizeof(struct pfn_info); frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK; -#if defined(__x86_64__) - frame_table = __va(alloc_boot_pages(frame_table_size, 4UL << 20)); -#elif defined(__i386__) - frame_table = (struct pfn_info *)FRAMETABLE_VIRT_START; - for ( i = 0; i < frame_table_size; i += (4UL << 20) ) { p = alloc_boot_pages(min(frame_table_size - i, 4UL << 20), 4UL << 20); if ( p == 0 ) panic("Not enough memory for frame table\n"); - idle_pg_table[(FRAMETABLE_VIRT_START + i) >> L2_PAGETABLE_SHIFT] = - mk_l2_pgentry(p | __PAGE_HYPERVISOR | _PAGE_PSE); + map_pages(idle_pg_table, FRAMETABLE_VIRT_START + i, p, + 4UL << 20, PAGE_HYPERVISOR); } -#endif memset(frame_table, 0, frame_table_size); } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 9942f35988..5bf8149168 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -55,6 +55,8 @@ boolean_param("ignorebiostables", opt_ignorebiostables); static int opt_watchdog = 0; boolean_param("watchdog", opt_watchdog); +int early_boot = 1; + unsigned long xenheap_phys_end; extern void arch_init_memory(void); @@ -594,6 +596,8 @@ void __init __start_xen(multiboot_info_t *mbi) (xenheap_phys_end-__pa(heap_start)) >> 20, (xenheap_phys_end-__pa(heap_start)) >> 10); + early_boot = 0; + /* Initialise the slab allocator. */ xmem_cache_init(); xmem_cache_sizes_init(max_page); diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index 16f1dd61a7..8e1375d242 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -29,30 +29,62 @@ unsigned long m2p_start_mfn; -static inline void set_pte_phys(unsigned long vaddr, - l1_pgentry_t entry) +/* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */ +int map_pages( + pagetable_t *pt, + unsigned long v, + unsigned long p, + unsigned long s, + unsigned long flags) { - l2_pgentry_t *l2ent; - l1_pgentry_t *l1ent; + l2_pgentry_t *pl2e; + l1_pgentry_t *pl1e; + void *newpg; - l2ent = &idle_pg_table[l2_table_offset(vaddr)]; - l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr); - *l1ent = entry; + while ( s != 0 ) + { + pl2e = &pt[l2_table_offset(v)]; - /* It's enough to flush this one mapping. */ - __flush_tlb_one(vaddr); -} + if ( ((s|v|p) & ((1<= __end_of_fixed_addresses) ) + BUG(); + map_pages(idle_pg_table, fix_to_virt(idx), p, PAGE_SIZE, flags); } diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index fe11c2cf3d..6760595580 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -27,39 +27,114 @@ #include #include -static inline void set_pte_phys(unsigned long vaddr, - l1_pgentry_t entry) +unsigned long m2p_start_mfn; /* XXX Kill this (in 32-bit code also). */ + +void *safe_page_alloc(void) { - l4_pgentry_t *l4ent; - l3_pgentry_t *l3ent; - l2_pgentry_t *l2ent; - l1_pgentry_t *l1ent; - - l4ent = &idle_pg_table[l4_table_offset(vaddr)]; - l3ent = l4_pgentry_to_l3(*l4ent) + l3_table_offset(vaddr); - l2ent = l3_pgentry_to_l2(*l3ent) + l2_table_offset(vaddr); - l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr); - *l1ent = entry; - - /* It's enough to flush this one mapping. */ - __flush_tlb_one(vaddr); + extern int early_boot; + if ( early_boot ) + return __va(alloc_boot_pages(PAGE_SIZE, PAGE_SIZE)); + return (void *)alloc_xenheap_page(); } - -void __set_fixmap(enum fixed_addresses idx, - l1_pgentry_t entry) +/* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */ +int map_pages( + pagetable_t *pt, + unsigned long v, + unsigned long p, + unsigned long s, + unsigned long flags) { - unsigned long address = fix_to_virt(idx); + l4_pgentry_t *pl4e; + l3_pgentry_t *pl3e; + l2_pgentry_t *pl2e; + l1_pgentry_t *pl1e; + void *newpg; - if ( likely(idx < __end_of_fixed_addresses) ) - set_pte_phys(address, entry); - else - printk("Invalid __set_fixmap\n"); + while ( s != 0 ) + { + pl4e = &pt[l4_table_offset(v)]; + if ( !(l4_pgentry_val(*pl4e) & _PAGE_PRESENT) ) + { + newpg = safe_page_alloc(); + clear_page(newpg); + *pl4e = mk_l4_pgentry(__pa(newpg) | __PAGE_HYPERVISOR); + } + + pl3e = l4_pgentry_to_l3(*pl4e) + l3_table_offset(v); + if ( !(l3_pgentry_val(*pl3e) & _PAGE_PRESENT) ) + { + newpg = safe_page_alloc(); + clear_page(newpg); + *pl3e = mk_l3_pgentry(__pa(newpg) | __PAGE_HYPERVISOR); + } + + pl2e = l3_pgentry_to_l2(*pl3e) + l2_table_offset(v); + + if ( ((s|v|p) & ((1<= __end_of_fixed_addresses) ) + BUG(); + map_pages(idle_pg_table, fix_to_virt(idx), p, PAGE_SIZE, flags); } void __init paging_init(void) { + void *newpt; + + /* Allocate and map the machine-to-phys table. */ + /* XXX TODO XXX */ + + /* Create page table for ioremap(). */ + newpt = (void *)alloc_xenheap_page(); + clear_page(newpt); + idle_pg_table[IOREMAP_VIRT_START >> L4_PAGETABLE_SHIFT] = + mk_l4_pgentry(__pa(newpt) | __PAGE_HYPERVISOR); + + /* Create read-only mapping of MPT for guest-OS use. */ + newpt = (void *)alloc_xenheap_page(); + clear_page(newpt); + idle_pg_table[RO_MPT_VIRT_START >> L4_PAGETABLE_SHIFT] = + mk_l4_pgentry((__pa(newpt) | __PAGE_HYPERVISOR | _PAGE_USER) & + ~_PAGE_RW); + /* XXX TODO: Copy appropriate L3 entries from RDWR_MPT_VIRT_START XXX */ + /* Set up linear page table mapping. */ idle_pg_table[LINEAR_PT_VIRT_START >> L4_PAGETABLE_SHIFT] = mk_l4_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR); diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 685621164f..1d45339f05 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -100,7 +100,10 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn)); #define XENHEAP_DEFAULT_MB (16) #define PML4_ENTRY_BITS 39 -#define PML4_ENTRY_BYTES (1UL<> 8) * 0xffff000000000000UL) | \ + (_slot ## UL << PML4_ENTRY_BITS)) /* * Memory layout: @@ -120,7 +123,13 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn)); * Shadow linear page table. * 0xffff820000000000 - 0xffff827fffffffff [512GB, 2^39 bytes, PML4:260] * Per-domain mappings (e.g., GDT, LDT). - * 0xffff828000000000 - 0xffff8287ffffffff [512GB, 2^39 bytes, PML4:261] + * 0xffff828000000000 - 0xffff8283ffffffff [16GB, 2^34 bytes, PML4:261] + * Machine-to-phys translation table. + * 0xffff828400000000 - 0xffff8287ffffffff [16GB, 2^34 bytes, PML4:261] + * Page-frame information array. + * 0xffff828800000000 - 0xffff828bffffffff [16GB, 2^34 bytes, PML4:261] + * ioremap()/fixmap area. + * 0xffff828c00000000 - 0xffff82ffffffffff [464GB, PML4:261] * Reserved for future use. * 0xffff830000000000 - 0xffff83ffffffffff [1TB, 2^40 bytes, PML4:262-263] * 1:1 direct mapping of all physical memory. Xen and its heap live here. @@ -130,26 +139,36 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn)); * Guest-defined use. */ + /* Hypervisor reserves PML4 slots 256 to 271 inclusive. */ -#define HYPERVISOR_VIRT_START (0xFFFF800000000000UL) -#define HYPERVISOR_VIRT_END (0xFFFF880000000000UL) +#define HYPERVISOR_VIRT_START (PML4_ADDR(256)) +#define HYPERVISOR_VIRT_END (HYPERVISOR_VIRT_START + PML4_ENTRY_BYTES*16) /* Slot 256: read-only guest-accessible machine-to-phys translation table. */ -#define RO_MPT_VIRT_START (HYPERVISOR_VIRT_START) +#define RO_MPT_VIRT_START (PML4_ADDR(256)) #define RO_MPT_VIRT_END (RO_MPT_VIRT_START + PML4_ENTRY_BYTES/2) /* Slot 257: read-only guest-accessible linear page table. */ -#define RO_LINEAR_PT_VIRT_START (RO_MPT_VIRT_END + PML4_ENTRY_BYTES/2) +#define RO_LINEAR_PT_VIRT_START (PML4_ADDR(257)) #define RO_LINEAR_PT_VIRT_END (RO_LINEAR_PT_VIRT_START + PML4_ENTRY_BYTES) /* Slot 258: linear page table (guest table). */ -#define LINEAR_PT_VIRT_START (RO_LINEAR_PT_VIRT_END) +#define LINEAR_PT_VIRT_START (PML4_ADDR(258)) #define LINEAR_PT_VIRT_END (LINEAR_PT_VIRT_START + PML4_ENTRY_BYTES) /* Slot 259: linear page table (shadow table). */ -#define SH_LINEAR_PT_VIRT_START (LINEAR_PT_VIRT_END) +#define SH_LINEAR_PT_VIRT_START (PML4_ADDR(259)) #define SH_LINEAR_PT_VIRT_END (SH_LINEAR_PT_VIRT_START + PML4_ENTRY_BYTES) /* Slot 260: per-domain mappings. */ -#define PERDOMAIN_VIRT_START (SH_LINEAR_PT_VIRT_END) +#define PERDOMAIN_VIRT_START (PML4_ADDR(260)) #define PERDOMAIN_VIRT_END (PERDOMAIN_VIRT_START + PML4_ENTRY_BYTES) +/* Slot 261: machine-to-phys conversion table (16GB). */ +#define RDWR_MPT_VIRT_START (PML4_ADDR(261)) +#define RDWR_MPT_VIRT_END (RDWR_MPT_VIRT_START + (16UL<<30)) +/* Slot 261: page-frame information array (16GB). */ +#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END) +#define FRAMETABLE_VIRT_END (FRAMETABLE_VIRT_START + (16UL<<30)) +/* Slot 261: ioremap()/fixmap area (16GB). */ +#define IOREMAP_VIRT_START (FRAMETABLE_VIRT_END) +#define IOREMAP_VIRT_END (IOREMAP_VIRT_START + (16UL<<30)) /* Slot 262-263: A direct 1:1 mapping of all of physical memory. */ -#define DIRECTMAP_VIRT_START (PERDOMAIN_VIRT_END + PML4_ENTRY_BYTES) +#define DIRECTMAP_VIRT_START (PML4_ADDR(262)) #define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + PML4_ENTRY_BYTES*2) #define PGT_base_page_table PGT_l4_page_table @@ -180,10 +199,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn)); /* Xen heap extends to end of 1:1 direct-mapped memory region. */ #define DIRECTMAP_VIRT_START (RO_MPT_VIRT_END) #define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + DIRECTMAP_PHYS_END) -#define XENHEAP_VIRT_START (DIRECTMAP_VIRT_START) -#define XENHEAP_VIRT_END (DIRECTMAP_VIRT_END) /* Machine-to-phys conversion table. */ -#define RDWR_MPT_VIRT_START (XENHEAP_VIRT_END) +#define RDWR_MPT_VIRT_START (DIRECTMAP_VIRT_END) #define RDWR_MPT_VIRT_END (RDWR_MPT_VIRT_START + (4*1024*1024)) /* Variable-length page-frame information array. */ #define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END) diff --git a/xen/include/asm-x86/domain_page.h b/xen/include/asm-x86/domain_page.h index d8cdf0b74e..3eae53933d 100644 --- a/xen/include/asm-x86/domain_page.h +++ b/xen/include/asm-x86/domain_page.h @@ -1,29 +1,5 @@ -/****************************************************************************** - * domain_page.h - * - * Allow temporary mapping of domain page frames into Xen space. - */ - -#ifndef __ASM_DOMAIN_PAGE_H__ -#define __ASM_DOMAIN_PAGE_H__ - -#include -#include - -extern unsigned long *mapcache; -#define MAPCACHE_ENTRIES 1024 - -/* - * Maps a given physical address, returning corresponding virtual address. - * The entire page containing that VA is now accessible until a - * corresponding call to unmap_domain_mem(). - */ -extern void *map_domain_mem(unsigned long pa); - -/* - * Pass a VA within a page previously mapped with map_domain_mem(). - * That page will then be removed from the mapping lists. - */ -extern void unmap_domain_mem(void *va); - -#endif /* __ASM_DOMAIN_PAGE_H__ */ +#ifdef __x86_64__ +#include +#else +#include +#endif diff --git a/xen/include/asm-x86/fixmap.h b/xen/include/asm-x86/fixmap.h index e854033fc5..e123cb791a 100644 --- a/xen/include/asm-x86/fixmap.h +++ b/xen/include/asm-x86/fixmap.h @@ -39,18 +39,18 @@ enum fixed_addresses { __end_of_fixed_addresses }; -#define FIXADDR_TOP (0xffffe000UL) +#define FIXADDR_TOP (IOREMAP_VIRT_END - PAGE_SIZE) #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) -extern void __set_fixmap(enum fixed_addresses idx, - l1_pgentry_t entry); +extern void __set_fixmap( + enum fixed_addresses idx, unsigned long p, unsigned long flags); #define set_fixmap(idx, phys) \ - __set_fixmap(idx, mk_l1_pgentry(phys|PAGE_HYPERVISOR)) + __set_fixmap(idx, phys, PAGE_HYPERVISOR) #define set_fixmap_nocache(idx, phys) \ - __set_fixmap(idx, mk_l1_pgentry(phys|PAGE_HYPERVISOR_NOCACHE)) + __set_fixmap(idx, phys, PAGE_HYPERVISOR_NOCACHE) #define fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 3c96144256..18c86e6245 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -222,17 +222,11 @@ void synchronise_pagetables(unsigned long cpu_mask); */ #undef phys_to_machine_mapping -#ifdef __x86_64__ -extern unsigned long *machine_to_phys_mapping; -extern unsigned long *phys_to_machine_mapping; -#define m2p_start_mfn virt_to_phys(machine_to_phys_mapping) -#else /* Don't call virt_to_phys on this: it isn't direct mapped. Using m2p_start_mfn instead. */ #define machine_to_phys_mapping ((unsigned long *)RDWR_MPT_VIRT_START) extern unsigned long m2p_start_mfn; #define phys_to_machine_mapping ((unsigned long *)PERDOMAIN_VIRT_START) -#endif #define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn) diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index a20d9dcb27..50a4f15b87 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -46,7 +46,6 @@ typedef struct { unsigned long l1_lo; } l1_pgentry_t; typedef struct { unsigned long l2_lo; } l2_pgentry_t; typedef struct { unsigned long l3_lo; } l3_pgentry_t; typedef struct { unsigned long l4_lo; } l4_pgentry_t; -typedef struct { unsigned long pt_lo; } pagetable_t; #endif /* !__ASSEMBLY__ */ /* Strip type from a table entry. */ @@ -54,14 +53,12 @@ typedef struct { unsigned long pt_lo; } pagetable_t; #define l2_pgentry_val(_x) ((_x).l2_lo) #define l3_pgentry_val(_x) ((_x).l3_lo) #define l4_pgentry_val(_x) ((_x).l4_lo) -#define pagetable_val(_x) ((_x).pt_lo) /* Add type to a table entry. */ #define mk_l1_pgentry(_x) ( (l1_pgentry_t) { (_x) } ) #define mk_l2_pgentry(_x) ( (l2_pgentry_t) { (_x) } ) #define mk_l3_pgentry(_x) ( (l3_pgentry_t) { (_x) } ) #define mk_l4_pgentry(_x) ( (l4_pgentry_t) { (_x) } ) -#define mk_pagetable(_x) ( (pagetable_t) { (_x) } ) /* Turn a typed table entry into a page index. */ #define l1_pgentry_to_pagenr(_x) (l1_pgentry_val(_x) >> PAGE_SHIFT) @@ -91,11 +88,23 @@ typedef struct { unsigned long pt_lo; } pagetable_t; ((_a) >> L2_PAGETABLE_SHIFT) #elif defined(__x86_64__) #define l2_table_offset(_a) \ - (((_a) >> L2_PAGETABLE_SHIFT) & (ENTRIES_PER_L2_PAGETABLE -1)) + (((_a) >> L2_PAGETABLE_SHIFT) & (ENTRIES_PER_L2_PAGETABLE - 1)) #define l3_table_offset(_a) \ - (((_a) >> L3_PAGETABLE_SHIFT) & (ENTRIES_PER_L3_PAGETABLE -1)) + (((_a) >> L3_PAGETABLE_SHIFT) & (ENTRIES_PER_L3_PAGETABLE - 1)) #define l4_table_offset(_a) \ - ((_a) >> L4_PAGETABLE_SHIFT) + (((_a) >> L4_PAGETABLE_SHIFT) & (ENTRIES_PER_L4_PAGETABLE - 1)) +#endif + +#if defined(__i386__) +#define pagetable_t l2_pgentry_t +#define pagetable_val(_x) ((_x).l2_lo) +#define mk_pagetable(_x) ( (l2_pgentry_t) { (_x) } ) +#define ENTRIES_PER_PAGETABLE ENTRIES_PER_L2_PAGETABLE +#elif defined(__x86_64__) +#define pagetable_t l4_pgentry_t +#define pagetable_val(_x) ((_x).l4_lo) +#define mk_pagetable(_x) ( (l4_pgentry_t) { (_x) } ) +#define ENTRIES_PER_PAGETABLE ENTRIES_PER_L4_PAGETABLE #endif #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) @@ -131,11 +140,7 @@ typedef struct { unsigned long pt_lo; } pagetable_t; #define va_to_l1mfn(_va) (l2_pgentry_val(linear_l2_table[_va>>L2_PAGETABLE_SHIFT]) >> PAGE_SHIFT) -#ifdef __i386__ -extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE]; -#else -extern l4_pgentry_t idle_pg_table[ENTRIES_PER_L4_PAGETABLE]; -#endif +extern pagetable_t idle_pg_table[ENTRIES_PER_PAGETABLE]; extern void paging_init(void); @@ -191,6 +196,7 @@ __asm__ __volatile__("invlpg %0": :"m" (*(char *) (__addr))) #define PAGE_HYPERVISOR_NOCACHE MAKE_GLOBAL(__PAGE_HYPERVISOR_NOCACHE) #ifndef __ASSEMBLY__ + static __inline__ int get_order(unsigned long size) { int order; @@ -205,6 +211,16 @@ static __inline__ int get_order(unsigned long size) } extern void zap_low_mappings(void); -#endif + +/* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */ +extern int +map_pages( + pagetable_t *pt, + unsigned long v, + unsigned long p, + unsigned long s, + unsigned long flags); + +#endif /* !__ASSEMBLY__ */ #endif /* __I386_PAGE_H__ */ diff --git a/xen/include/asm-x86/x86_32/domain_page.h b/xen/include/asm-x86/x86_32/domain_page.h new file mode 100644 index 0000000000..d8cdf0b74e --- /dev/null +++ b/xen/include/asm-x86/x86_32/domain_page.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * domain_page.h + * + * Allow temporary mapping of domain page frames into Xen space. + */ + +#ifndef __ASM_DOMAIN_PAGE_H__ +#define __ASM_DOMAIN_PAGE_H__ + +#include +#include + +extern unsigned long *mapcache; +#define MAPCACHE_ENTRIES 1024 + +/* + * Maps a given physical address, returning corresponding virtual address. + * The entire page containing that VA is now accessible until a + * corresponding call to unmap_domain_mem(). + */ +extern void *map_domain_mem(unsigned long pa); + +/* + * Pass a VA within a page previously mapped with map_domain_mem(). + * That page will then be removed from the mapping lists. + */ +extern void unmap_domain_mem(void *va); + +#endif /* __ASM_DOMAIN_PAGE_H__ */ diff --git a/xen/include/asm-x86/x86_64/domain_page.h b/xen/include/asm-x86/x86_64/domain_page.h new file mode 100644 index 0000000000..8a6081cde4 --- /dev/null +++ b/xen/include/asm-x86/x86_64/domain_page.h @@ -0,0 +1,13 @@ +/****************************************************************************** + * domain_page.h + * + * This is a trivial no-op on x86/64, where we can 1:1 map all RAM. + */ + +#ifndef __ASM_DOMAIN_PAGE_H__ +#define __ASM_DOMAIN_PAGE_H__ + +#define map_domain_mem(_pa) phys_to_virt(_pa) +#define unmap_domain_mem(_va) ((void)(_va)) + +#endif /* __ASM_DOMAIN_PAGE_H__ */ -- 2.30.2